有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何在安卓中绘制从Firebase数据库检索到的数据

我正在从Firebase实时数据库检索数据。我在检索数据方面没有问题。但当我疲于将检索到的数据写入graph view时。添加几个点后,程序崩溃,出现以下错误:

错误

E/AndroidRuntime: FATAL EXCEPTION: Thread-10
     Process: com.example.firebase, PID: 6687
     java.util.ConcurrentModificationException
         at java.util.ArrayList$Itr.next(ArrayList.java:860)
         at com.jjoe64.graphview.series.BaseSeries.appendData(BaseSeries.java:445)
         at com.jjoe64.graphview.series.LineGraphSeries.appendData(LineGraphSeries.java:646)
         at com.jjoe64.graphview.series.BaseSeries.appendData(BaseSeries.java:464)
         at com.example.firebase.MainActivity.AddPointChart(MainActivity.java:27)
         at com.example.firebase.MainActivity.access$000(MainActivity.java:24)
         at com.example.firebase.MainActivity$MyThread.run(MainActivity.java:38)

这是我的代码:

 private void AddPointChart(float Value){
            x++;
            series.appendData(new DataPoint(x,Value),true,1500);
            graph.addSeries(series);
    }

    class MyThread extends Thread{
        public void run(){
            float Value;
            while(true)
            {
                if (!kuyruk.isEmpty()){
                    Value= Float.parseFloat(String.valueOf(kuyruk.poll()));
                    AddPointChart(Value);
                }
            }
        }
    }
    TextView s_indexNo,s_Value;
    Button btn;
    DatabaseReference reff;
    GraphView graph;
    LineGraphSeries series;
    FirebaseDatabase database;

    public Queue kuyruk=new LinkedList();
    int x=0;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        s_indexNo=(TextView)findViewById(R.id.txtindex);
        s_Value=(TextView)findViewById(R.id.txtvalue);
        btn=(Button)findViewById(R.id.button2);
        graph=(GraphView)findViewById(R.id.graph);
        series=new LineGraphSeries();
        graph.addSeries(series);
        database = FirebaseDatabase.getInstance();
        reff=database.getReference("ABC123");

        btn.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View view){
                reff= FirebaseDatabase.getInstance().getReference().child("ABC123");
                reff.addValueEventListener(new ValueEventListener() {
                    @Override
                    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                        MyThread t=new MyThread();
                        t.start();
                        float Value=Float.parseFloat(dataSnapshot.child("Value").getValue().toString());
                        kuyruk.offer(Value);
                    }
                    @Override
                    public void onCancelled(@NonNull DatabaseError databaseError) {
                    }
                });
            }
        });
    }

共 (1) 个答案

  1. # 1 楼答案

    只要再次运行onDataChange方法,就可以启动第二个线程来更新GraphView。这会导致两个线程同时写入同一个图形视图,从而导致错误

    要解决此问题,您应该在活动中存储线程的引用:

    MyThread graphUpdater;
    

    然后,将线程创建移出ValueEventListener,例如

    btn.setOnClickListener(new View.OnClickListener(){
        @Override
        public void onClick(View view) {
            // check if thread is already created
            if (graphUpdater != null) {
                // if already running, ignore button press
                // you could stop your thread here to stop the graph plotting
                // if you want
                return;
            }
            reff= FirebaseDatabase.getInstance().getReference().child("ABC123");
            reff.addValueEventListener(new ValueEventListener() {
                @Override
                public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                    float Value=Float.parseFloat(dataSnapshot.child("Value").getValue().toString());
                    kuyruk.offer(Value);
                }
                @Override
                public void onCancelled(@NonNull DatabaseError databaseError) {
                }
            });
            // create one thread
            graphUpdater = new MyThread();
            graphUpdater.start();
        }
    });